
/**
 * @copyright Copyright (c) 2021 Oray Inc. All rights reserverd.
 * No Part of this file may be reproduced, stored
 * in a retrieval system, or transmitted, in any form, or by any means,
 * electronic, mechanical, photocopying, recording, or otherwise,
 * without the prior consent of Oray Inc.
 * 
 * @file sock-wrapper.hpp
 * @author sunchao (sunchao@oray.com)
 * @brief sock-wrapper
 * @version 0.1
 * @date 2021-12-22
 */
#ifndef _UDS_SERVER_H_
#define _UDS_SERVER_H_
#include <string>
#include <map>
#include <vector>
#include <sys/poll.h>
#include <sys/epoll.h>
#include "udsCommon.h"
#include "template/template_thread.hpp"

#define MAX_LISTEN_FD_NUM 10
#define RECV_WAIT_TIME 1000

typedef std::map<int, udsFunc> udsServerFuncMap;
typedef std::map<int, stdUdsFunc> udsServerStdFuncMap;

class udsServer
{
public:
    udsServer();
    ~udsServer();

    bool serverStart();
    bool insertCb(int cmd, udsFunc func);
    bool insertCb_v1(int cmd, stdUdsFunc func);

    int createListenUds(const char *path);
    int createListenTcp(const int port);

    int sendMsg(int fd, int cmd, char *p_buf, size_t buf_len);
    int sendPacks(int fd, int cmd, void **frame_addr, size_t *frame_size, int pack_count);

    bool recvMsg(p_UdsHandler pHandler, int timout);

    void destroyHandle(p_UdsHandler pHandler);
    void destroyFd(int fd);

    //################# 内部线程逻辑使用 start ##############
    void udsPollDisponse();
    //################# 内部线程逻辑使用 end ##############
private:
    

    //将fd 移除 poll 监听容器
    void _removePollFd(int fd);
    //将fd 加入 poll 监听容器
    void _pushPollFd(int fd);
    
    //检测fd 是否是 listen fd
    bool _checkFds(int chkfd);
    //执行 任务回调
    bool _doCmd(p_UdsHandler pCmd);

    //执行 任务回调
    bool _doCmd_v1(p_UdsHandler pCmd);


private:
    std::map<int,int> listenFdMap_;  //listen fd 存放容器
    std::vector<pollfd> pollFdVector_;  // poll 监听的fd 容器
    mutable std::mutex pollFdVectorMutex_; //pollFdVector_ 编辑锁
    template_thread<udsServer> udsListenThread_; //poll_dispose 线程句柄

    udsServerFuncMap udsFuncMap_; // 注册的事件回调存放容器
    udsServerStdFuncMap stdUdsFuncMap_;// 注册的事件回调存放容器 (std::function)
};


class uds_server_base {
public:
	uds_server_base(const char * uds_path);

	virtual ~uds_server_base();


	/**
	 * @brief: 根据 cmd 注册对应的回调函数	
	 *
	 * @param cmd 命令码
	 * @param func 函数地址
	 */
	void register_cb(int cmd, void * func(void *));

	/**
	 * @brief:	运行server (注意这里会 block)
	 */
	void loop();
private:
	udsServer * _instance = NULL;
	bool _init = false;
};

#endif //_UDS_CLIENT_H
